'''
Program Assignment:	Assignment 2
Name:			Alberto Massa                                                                      
Date:			11/08/2010                  
Description:            This file contains main window and integration glue-code 
			between gui widget and core function counter functions
'''

'''
Listing Contents:

Compilation instructions
	funcounter and gui package must be in PYTHONPATH or in first subdirectory

Includes and dependecies
	PyQt4 are required.
	Ui_FunctionCounter class made with QtDesigner

Class and procedures declarations:                                                                                     	
	get_python, get_python_factory: LanguageFactory utilites
	FunconterMainWIndow: main class
'''

import sys

from PyQt4.QtGui import QApplication, QMainWindow
from PyQt4.QtGui import QFileDialog
from PyQt4.QtCore import SIGNAL

import funcounter as f
from gui import TreeWidget, TableWidget, Ui_FunctionCounter as GUI

def get_python():
	python = f.Language('python', ['py'], f.PythonParser)
	return python, 'py'

def get_pythonic_factory():
	factory = f.LanguageFactory()
	factory.addlang(get_python()[0])
	return factory


class FuncounterMainWindow(QMainWindow, GUI):
	'''
	Main class. Integrates funcounter with a custom graphical interface.
	'''

	def __init__(self, parent=None):
		'''
		Constructor.
		parent is QMainWindow optional parameter
		'''

		super(FuncounterMainWindow, self).__init__(parent)

		factory = get_pythonic_factory()

		self.setupUi(self)

		self.tree_widget = TreeWidget(self.tree_container)
		self.table_widget = TableWidget(self.table_container)

		# wire gui and core modules
		self.connect(self.open, SIGNAL("clicked()"), self.open_dir)
		self.connect(self.table_widget, SIGNAL("itemClicked(QTableWidgetItem*)"), self.table_item_clicked)
		
	def table_item_clicked(self, selected):
		'''
		Handler function for clicked() event on QTableWidgetItem object
		'''
		self.table_widget.selectRow(selected.row())
		pathItem = self.table_widget.item(selected.row(), 1)
		path = str(pathItem.text())
		self.open_tree(self.table_widget.path2codefile[path])

	def open_dir(self):
		'''
		Open selected dir with CodeFileWalker funcounter class.
		Populate TableWidget item.
		Clear TreeWidget.
		Update QLabel path_label, total_loc, total_nfunc.
		'''

		dirname = QFileDialog.getExistingDirectory(self, "Open directory")
		dirname = str(dirname)
		walker = f.CodeFileWalker()
		files = list(walker.open_directory(dirname))
		self.table_widget.populate(files)

		self.tree_widget.clear()
		self.path_label.setText("Path: "+dirname)
		locs, nfuncs = self.count_totals(files)
		self.total_loc.setText("Total LOC: {0}".format(locs))
		self.total_nfunc.setText("Total functions: {0}".format(nfuncs))

	def count_totals(self, files):
		'''
		Counts all loc and function numbers of a list of CodeFile object.
		Return the tuple (total_loc, total_function_numbers)
		'''
		locs = 0
		nfuncs = 0
		for _file in files:
			parser = _file.language.visitor
			parser.parse_file(_file)
			locs += _file.root.line
			nfuncs += len(_file.root)
		return locs, nfuncs


	def open_tree(self, _file):
		'''
		Populate TreeWidget.
		_file must be a CodeFile object.
		'''
		parser = _file.language.visitor
		parser.parse_file(_file)

		self.tree_widget.clear()
		_file.root.accept(self.tree_widget)

def main(args):
	'''
	Launcher functions.
	Take command line args options.
	Start QAppliction.
	'''
	app = QApplication(args)
	window = FuncounterMainWindow()
	window.show()
	sys.exit(app.exec_())

if __name__ == "__main__":
	main([])
